import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;


public class SoundFile {
	private InputStream waveStream = null;
    //private final int EXTERNAL_BUFFER_SIZE = 524288; // 128Kb
    private AudioFormat audioFormat = null;
    private	AudioInputStream audioInputStream = null;
    private long timeStep = 100;  // unit is millisecond
	private long frameTimeCounter = 0;
	
    public long getTimeStep() {
		return timeStep;
	}

	public void setTimeStep(long timeStep) {
		this.timeStep = timeStep;
	}

    
    public SoundFile(String fileName){
    	// opens the inputStream
    	try {
    		this.waveStream = new FileInputStream(fileName);
    	} catch (FileNotFoundException e) {
    	    e.printStackTrace();
    	    return;
    	}

		try {
		    audioInputStream = AudioSystem.getAudioInputStream(this.waveStream);
		} catch (UnsupportedAudioFileException e1) {
		    e1.printStackTrace();
		    return;
		} catch (IOException e1) {
		    e1.printStackTrace();
		    return;
		}
		
		// Obtain the information about the AudioInputStream
		audioFormat = audioInputStream.getFormat();
    }
    
    public AudioFormat getAudioFormat(){
    	return audioFormat;
    }
    
    public boolean ReadNextFrame(SoundFrame frame){
    	
		try {
		    //Read raw data
		    int offset = 0;
	        int numRead = 0;
	        int length = frame.rawBuffer.length;
	        while (offset < length && (numRead =
	        	audioInputStream.read(frame.rawBuffer, offset, length-offset)) >= 0) {
	        	if(numRead == -1)
	        		return false;
	            offset += numRead;
	        }
	        
	        // generate frame timestamp
	        frame.timeStamp = frameTimeCounter;
	        frameTimeCounter += timeStep;
		} catch (IOException e1) {
		   e1.printStackTrace();
		   return false;
		} 
    	return true;
    }
}
